package com.xinhe.web.service;

import com.xinhe.web.common.BusinessException;
import com.xinhe.web.common.Result;
import com.xinhe.web.config.WxConfigManager;
import com.xinhe.web.entity.ValueConfig;
import com.xinhe.web.entity.WeixinConfig;
import com.xinhe.web.entity.WeixinUser;
import com.xinhe.web.reposity.ValueConfigRepository;
import com.xinhe.web.reposity.WeixinConfigRepository;
import com.xinhe.web.reposity.WeixinUserRepository;
import com.xinhe.web.vo.UserRegisterModel;
import com.xinhe.web.weixin.SendTemplateMessageModel;
import com.xinhe.web.weixin.WeixinNotifyUtil;
import com.xinhe.web.weixin.model.WeixinLoginModel;
import com.xinhe.web.weixin.service.WeixinUtilBean;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class WeixinService {
    @Autowired
    ValueConfigRepository valueConfigRepository;
    @Autowired
    WeixinUserRepository weixinUserRepository;
    @Autowired
    WeixinConfigRepository weixinConfigRepository;
    @Autowired
    private WeixinUtilBean weixinUtilBean;
    @Autowired
    WxConfigManager wxConfigManager;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    WeixinNotifyUtil weixinNotifyUtil;
    @Autowired
    UserService userService;
    @Autowired(required = false)
    private MemberService weixinUserExtendService;

    @Retryable(value = {BusinessException.class}, maxAttempts = 1, backoff = @Backoff(delay = 1L, multiplier = 0.0D))
    public Result sendTemplateMessage(SendTemplateMessageModel model) {
        //小程序微信配置ID 519802482830868480
        Long miniProgramId = Long.valueOf(valueConfigRepository.findById("weixin_config_id_mini_program").get().getValue());
        //公众号id
        Long serviceId = Long.valueOf(valueConfigRepository.findById("weixin_config_id_service").get().getValue());
        WeixinUser weixinUser = this.weixinUserRepository.findOneByConfigIdAndUserId(serviceId, model.getUserId());
        if (weixinUser == null) {
            log.error("用户{}未关注公众号", model.getUserId());
            return Result.failed(1001,"用户"+model.getUserId()+"未关注公众号");
        }
        WeixinConfig weixinConfig = this.weixinConfigRepository.findById(miniProgramId).get();
        String accessToken = this.weixinUtilBean.getAccessToken(serviceId);
        String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", new Object[] { accessToken });

        WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
        miniProgram.setAppid(weixinConfig.getAppId());
        miniProgram.setPagePath(model.getPagePath());
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder().templateId(model.getTemplateId()).url(url).toUser(weixinUser.getOpenid()).miniProgram(miniProgram).build();
        model.getData().forEach((k, v) -> templateMessage.addData(new WxMpTemplateData(k, v)));
        try {
            String msgId = this.wxConfigManager.getWxMpService().getTemplateMsgService().sendTemplateMsg(templateMessage);
            log.debug("公众号模板（跳转小程序）MSG_ID：{}", msgId);
            return Result.ok(msgId);
        } catch (WxErrorException e) {
            log.error("公众号模板（跳转小程序）发送失败：{}", e.getMessage());
            return Result.ok(1003,e.getMessage());
        }
    }
    @Transactional(rollbackFor = Exception.class)
    public void weixinUserAttentionNotify(Long configId) {
        log.info("微信服务号回调成功");
        String method = this.request.getMethod();
        if (method.equals("GET")) {
            String timestamp = this.request.getParameter("timestamp");
            String nonce = this.request.getParameter("nonce");
            String echostr = this.request.getParameter("echostr");
            String token = "xqg1024";
            List<String> params = new ArrayList<>();
            params.add(token);
            params.add(timestamp);
            params.add(nonce);

            params.sort(String::compareTo);



            respWeixinMessage(this.response, echostr);
        } else {

            Map<String, String> wxData = this.weixinNotifyUtil.getNotifyData();
            if (((String)wxData.get("MsgType")).equals("event"))
            {
                if (((String)wxData.get("Event")).equals("subscribe")) {

                    CloseableHttpClient httpClient = HttpClients.createDefault();
                    String openId = wxData.get("FromUserName");
                    String url = String.format("https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN", new Object[] { this.weixinUtilBean
                            .getAccessToken(configId), openId });
                    HttpGet httpGet = new HttpGet(url);
                    String respJson = null;
                    try {
                        CloseableHttpResponse userHttpResp = httpClient.execute((HttpUriRequest)httpGet);
                        HttpEntity userEntity = userHttpResp.getEntity();
                        respJson = EntityUtils.toString(userEntity, "UTF-8");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(respJson);
                    log.info("关注服务号回调成功--->获取用户信息,{}" + jsonObject.toString());
                    WeixinLoginModel loginModel = new WeixinLoginModel();
                    loginModel.setConfigId(configId);
                    loginModel.setOpenid(jsonObject.getString("openid"));
                    loginModel.setUnionid(jsonObject.getString("unionid"));
                    loginModel.setIconPath(jsonObject.getString("headimgurl"));
                    loginModel.setNickname(jsonObject.getString("nickname"));
                    Long roleId = Long.valueOf(this.valueConfigRepository.findById("role_id_weixin_attention").get().getValue());
                    WeixinUser weixinUser = this.weixinUserRepository.findOneByOpenid(jsonObject.getString("openid"));
                    if (weixinUser == null) {
                        weixinUser = new WeixinUser();
                        weixinUser.setOpenid(jsonObject.getString("openid"));
                        weixinUser.setUnionid(jsonObject.getString("unionid"));
                        weixinUser.setConfigId(configId);
                        List<WeixinUser> weixinUsers = this.weixinUserRepository.findByUnionid(weixinUser.getUnionid());
                        if (CollectionUtils.isNotEmpty(weixinUsers)) {
                            WeixinUser otherWeixinUser = weixinUsers.get(0);
                            weixinUser.setUserId(otherWeixinUser.getUserId());
                        }
                        if (null == weixinUser.getUserId()) {
                            Result userResult = this.userService.registerUser(new UserRegisterModel(null, null, null, new Long[] { roleId }));
                            if (0!= userResult.getCode()) {
                                throw new BusinessException(3010,userResult.getMessage());
                            }
                            weixinUser.setUserId((Long)userResult.getData());
                        }
                        if (this.weixinUserExtendService != null) {
                            this.weixinUserExtendService.saveWeixinUserExtend(weixinUser);
                        }
                        this.weixinUserRepository.save(weixinUser);
                    }
                }
            }
            respWeixinMessage(this.response, "success");
        }
    }
    private void respWeixinMessage(HttpServletResponse response, String message) {
        try {
            ServletOutputStream servletOutputStream = response.getOutputStream();
            servletOutputStream.write(message.getBytes());
            servletOutputStream.close();
        } catch (IOException var4) {
            var4.printStackTrace();
        }
    }

    /*private static final String CHARSET = "UTF-8";

    private static final String SUCCESS = "success";

    @Autowired
    private WeixinUtilBean weixinUtilBean;

    @Autowired
    private IValueConfigCache valueConfigCache;

    @Autowired
    private IWeixinConfigDao weixinConfigDao;

    @Autowired
    private WxConfigManager wxConfigManager;


    @Autowired
    private WeixinNotifyUtil weixinNotifyUtil;
    @Autowired
    private IWeixinUserDao weixinUserDao;
    @Autowired
    private IUserService userService;
    @Autowired(required = false)
    private IWeixinUserExtendService weixinUserExtendService;
    @Autowired
    private IValueConfigService valueConfigService;
    private static final String TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";

    @Retryable(value = {BusinessException.class}, maxAttempts = 1, backoff = @Backoff(delay = 1L, multiplier = 0.0D))
    public BeanResult<String> sendTemplateMessageUrl(SendTemplateMessageUrlModel model) {
        BeanResult<String> result = new BeanResult();
        String accessToken = this.weixinUtilBean.getAccessToken(this.valueConfigCache.getLong("weixin_config_id_service"));
        String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", new Object[] { accessToken });

        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder().templateId(model.getTemplateId()).url(url).toUser(model.getOpenId()).url(model.getJumpUrl()).build();
        model.getData().forEach((k, v) -> paramWxMpTemplateMessage.addData(new WxMpTemplateData(k, v)));
        try {
            String msgId = this.wxConfigManager.getWxMpService().getTemplateMsgService().sendTemplateMsg(templateMessage);
            log.error("公众号模板（跳转网页）MSG_ID：{}", msgId);
            result.setItem(msgId);
        } catch (WxErrorException e) {
            log.error("公众号模板（跳转网页）发送失败：{}", e.getMessage());
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

    @Recover
    private BeanResult<String> sendTemplateMessageRecover(BusinessException e, SendTemplateMessageModel model) {
        BeanResult<String> result = new BeanResult();
        JSONObject jsonObject = JSONObject.fromObject(e.getMessage());
        int errcode = jsonObject.getInt("errcode");
        if (errcode == 40001 || errcode == 42001) {


            this.weixinUtilBean.refreshWeixinFlag(this.valueConfigCache.getLong("weixin_config_id_service"));
            return sendTemplateMessage(model);
        }
        log.error("公众号模板（跳转小程序）方法重试失败：{}", e.getMessage());
        result.addErrorView(jsonObject.toString());
        return result;
    }

    @Recover
    private BeanResult<String> sendTemplateMessageUrlRecover(BusinessException e, SendTemplateMessageUrlModel model) {
        BeanResult<String> result = new BeanResult();
        JSONObject jsonObject = JSONObject.fromObject(e.getMessage());
        int errcode = jsonObject.getInt("errcode");
        if (errcode == 40001 || errcode == 42001) {


            this.weixinUtilBean.refreshWeixinFlag(this.valueConfigCache.getLong("weixin_config_id_service"));
            return sendTemplateMessageUrl(model);
        }
        log.error("公众号模板（跳转网页）方法重试失败：{}", e.getMessage());
        result.addErrorView(jsonObject.toString());
        return result;
    }

    */
}
